package com.sheng.leetcode.year2023.month07.day14;

import org.junit.Test;

/**
 * @author liusheng
 * @date 2023/07/14
 * <p>
 * 979. 在二叉树中分配硬币<p>
 * <p>
 * 给定一个有 N 个结点的二叉树的根结点 root，树中的每个结点上都对应有 node.val 枚硬币，并且总共有 N 枚硬币。<p>
 * 在一次移动中，我们可以选择两个相邻的结点，然后将一枚硬币从其中一个结点移动到另一个结点。<p>
 * (移动可以是从父结点到子结点，或者从子结点移动到父结点。)。<p>
 * 返回使每个结点上只有一枚硬币所需的移动次数。<p>
 * <p>
 * 示例 1：<p>
 * 输入：[3,0,0]<p>
 * 输出：2<p>
 * 解释：从树的根结点开始，我们将一枚硬币移到它的左子结点上，一枚硬币移到它的右子结点上。<p>
 * <p>
 * 示例 2：<p>
 * 输入：[0,3,0]<p>
 * 输出：3<p>
 * 解释：从根结点的左子结点开始，我们将两枚硬币移到根结点上 [移动两次]。然后，我们把一枚硬币从根结点移到右子结点上。<p>
 * <p>
 * 示例 3：<p>
 * 输入：[1,0,2]<p>
 * 输出：2<p>
 * <p>
 * 示例 4：<p>
 * 输入：[1,0,0,null,3]<p>
 * 输出：4<p>
 * <p>
 * 提示：<p>
 * 1<= N <= 100<p>
 * 0 <= node.val <= N<p>
 * <p>
 * 来源：力扣（LeetCode）<p>
 * 链接：<a href="https://leetcode.cn/problems/distribute-coins-in-binary-tree">979. 在二叉树中分配硬币</a><p>
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。<p>
 */
public class LeetCode0979 {

    @Test
    public void test01() {
//        TreeNode root = new TreeNode(3, new TreeNode(0), new TreeNode(0));
//        TreeNode root = new TreeNode(0, new TreeNode(3), new TreeNode(0));
//        TreeNode root = new TreeNode(1, new TreeNode(0), new TreeNode(2));
        TreeNode root = new TreeNode(1, new TreeNode(0), new TreeNode(0, null, new TreeNode(3)));
        System.out.println(new Solution().distributeCoins(root));
    }
}

class Solution {

    int ans = 0;

    public int distributeCoins(TreeNode root) {
        dfs(root);
        return Math.abs(ans);
    }

    public int dfs(TreeNode root) {
        // 假设左边有多余的金币，先全部移动到根结点，设为 left，左边结点有缺少的金币，全部从根结点获取，设置为 -left
        // 假设右边有多余的金币，先全部移动到根结点，设为 right，右边结点有缺少的金币，全部从根结点获取，设置为 -right
        // 左右相加即可
        if (root == null) {
            return 0;
        }
        int left = dfs(root.left);
        int right = dfs(root.right);
        ans += Math.abs(left) + Math.abs(right);
        return left + right + root.val - 1;
    }
}

// Definition for a binary tree node.
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode() {
    }

    TreeNode(int val) {
        this.val = val;
    }

    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

